<?php
/**
 * Created by PhpStorm.
 * User: Keter
 * Date: 2016/7/28
 * Time: 20:51
 */
class SocketRequest extends DatabaseBase
{
    /**
     * @var $socket socket连接
     */
    public $socket;

    /**
     * 连接
     * @param $host
     * @param $port
     * @param int $timeout
     * @param bool $persistent
     * @return bool|resource
     * @throws Exception
     */
    public function connect($host, $port, $timeout = 3, $persistent = false)
    {
        if ($persistent) {
            $this->socket = @pfsockopen($host, $port, $errCode, $errorMsg, $timeout);
        } else {
            $this->socket = @fsockopen($host, $port, $errCode, $errorMsg, $timeout);
        }

        if ($errCode || empty($this->socket)) {
            return $this->throwError($errorMsg, $errCode);
        }

        return $this->socket;
    }

    /**
     * 写入
     * @param $data
     * @return int
     */
    public function write($data)
    {
        return @fwrite($this->socket, $data, strlen($data));
    }

    /**
     * 读取
     * @param int $length
     * @return bool|string
     */
    public function read($length = 512)
    {
        if (!@feof($this->socket)) {
            return @fread($this->socket, $length);
        } else {
            return false;
        }
    }

    /**
     * 关闭
     */
    public function close()
    {
        return @fclose($this->socket);
    }

    /**
     * 数据请求
     * @param $host
     * @param $port
     * @param $data
     * @param int $timeout
     * @return bool|string
     * @throws Exception
     */
    public function request($host, $port, $data, $timeout = 3)
    {
        $content = json_encode($data, JSON_UNESCAPED_UNICODE);
        $content = pack("n", strlen($content)) . $content;
        $result = '';

        try {
            $this->i('socket_request_connect', ['server'=> $host, 'port' => $port]);
            $this->connect($host, $port, $timeout);
            $ret = $this->write($content);

            if ($ret) {
                $lenInfo = unpack('C2', $this->read(2));
                $length  = 0;
                if ($lenInfo[1]) {
                    $length = $lenInfo[1] * 256;
                } elseif ($lenInfo[2]) {
                    $length = $lenInfo[2] * 1;
                }
                if ($length) {
                    $result = $this->read($length);
                }
            }
            $this->close();
        } catch (Exception $e) {
            $msg = @iconv("GBK", "UTF-8", $e->getMessage());
            if ($msg) {
                $this->e($msg);
            } else {
                $this->e('failed_socket_request');
            }
            return $this->throwError('failed_socket_request');
        }

        return $result;
    }
}